//
//  TwitterClient.m
//  TwitterFon
//
//  Created by kaz on 7/13/08.
//  Copyright naan studio 2008. All rights reserved.
//

#import "DirectMessage.h"
#import "TwitterClient.h"
#import "StringUtil.h"
#import "JSON.h"
#import "URLStore.h"
#import "GuaziAppDelegate.h"
#import "FriendGroup.h"
#import "OperationLog.h"

static 
NSString* sMethods[4] = {
    @"statuses/friends_timeline",
    @"statuses/mentions",
    @"direct_messages",
    @"direct_messages/sent",
};


@implementation TwitterClient

@synthesize request;
@synthesize context;
@synthesize hasError;
@synthesize errorMessage;
@synthesize errorDetail;

- (id)initWithTarget:(id)aDelegate action:(SEL)anAction
{
    [super initWithDelegate:aDelegate];
    action = anAction;
    hasError = false;
    return self;
}

- (void)dealloc
{
    [errorMessage release];
    [errorDetail release];
    [super dealloc];
}

- (void)getTimeline:(TweetType)type params:(NSDictionary*)params
{
    request = type;
    needAuth = true;
    
	//NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/%@.json", sMethods[type]];
	NSString* url = nil;
	if ( type == TWEET_TYPE_FRIENDS ) {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendsTimeline format:@"json"];
	}
	else if ( type == TWEET_TYPE_REPLIES ) {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodMentions format:@"json"];
	}
	else if ( type == TWEET_TYPE_MESSAGES ) {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodMessageRelation format:@"json"];
	}
    
    int i = 0;
    for (id key in params) {
        NSString *value = [params objectForKey:key];
        if (i == 0) {
            url = [NSString stringWithFormat:@"%@?%@=%@", url, key, value];
        }
        else {
            url = [NSString stringWithFormat:@"%@&%@=%@", url, key, value];
        }
        ++i;
    }
    
    [super get:url];
}

/*
- (void)getUserTimeline:(NSString*)screen_name params:(NSDictionary*)params
{
    needAuth = true;
    NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/statuses/user_timeline.json?screen_name=%@", screen_name];
    
    int i = 0;
    for (id key in params) {
        NSString *value = [params objectForKey:key];
        if (i == 0) {
            url = [NSString stringWithFormat:@"%@?%@=%@", url, key, value];
        }
        else {
            url = [NSString stringWithFormat:@"%@&%@=%@", url, key, value];
        }
        ++i;
    }
    [super get:url];
}
 */

- (void) getUserTimeline:(long long)userId params:(NSDictionary *)params
{
    needAuth = true;
	NSString *s = [[URLStore sharedInstance] urlForKey:kAPIMethodUserTimeline format:@"json"];
    NSString *url = [NSString stringWithFormat:@"%@?userId=%lld", s, userId];
    
    int i = 0;
    for (id key in params) {
        NSString *value = [params objectForKey:key];
		if ( [url rangeOfString:@"?"].location == NSNotFound ) {
            url = [NSString stringWithFormat:@"%@?%@=%@", url, key, value];
		}
		else {
            url = [NSString stringWithFormat:@"%@&%@=%@", url, key, value];
		}
        ++i;
    }
    [super get:url];
}


- (void)getUser:(NSString*)screen_name
{
    needAuth = true;
	//changed by zhaoqi
    //NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/users/show/%@.json", screen_name];
	NSString* url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/users/show.json?screen_name=%@&needURL=N&needFace=N", screen_name];
    [super get:url];
}


- (void) getUserById:(sqlite_int64)userId
{
	needAuth = true;
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodUserProfile format:@"json"];
	NSString* url2 = [NSString stringWithFormat:@"%@?userId=%lld", url, userId];
	[super get:url2];
}

- (void)getMessage:(sqlite_int64)statusId
{
    needAuth = true;
	//changed by zhaoqi
    NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/statuses/show/:%lld.json", statusId];
    [super get:url];
}


- (void) getMessageConversation:(sqlite_int64)userId
{
	needAuth = true;
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodMessageConversation format:@"json"];
	NSString* url = [NSString stringWithFormat:@"%@?userId=%lld&pageNo=0&rowsPerPage=200", s, userId];
	[super get:url];
}


- (void)post:(NSString*)tweet inReplyTo:(sqlite_int64)statusId 
{
    [self post:tweet inReplyTo:statusId attach:nil];
}


- (void)post:(NSString*)tweet inReplyTo:(sqlite_int64)statusId attach:(NSDictionary*)attach
{
    needAuth = true;
    
    //NSString* url = @"http://api.t.sina.com.cn/statuses/update.json";
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodPostTweet format:@"json"];
    NSString* postString;
	if ( statusId > 0 ) {
		postString = [NSString stringWithFormat:@"content=%@&ossource=MB&ossourceName=iphone&in_reply_to_status_id=%lld",
								[tweet encodeAsURIComponent], statusId];
	}
	else {
		postString = [NSString stringWithFormat:@"content=%@&ossource=MB&ossourceName=iphone",
								[tweet encodeAsURIComponent]];
	}
    
    NSLog(@"url=%@", url);
    if ( attach && [attach count] > 0 ) {
        NSString* attachPath = [attach objectForKey:@"attachPath"];
        NSString* attachType = [attach objectForKey:@"attachType"];
        NSString* attachFilename = [attach objectForKey:@"attachFilename"];
        postString = [postString stringByAppendingFormat:@"&attachPath=%@&attachType=%@&attachFilename=%@", [attachPath encodeAsURIComponent], attachType, [attachFilename encodeAsURIComponent] ];
        NSLog(@"postString=%@", postString);
    }
	

    [self post:url body:postString];
}


- (void) postGroup:(NSString*)tweet group:(FriendGroup*)group
{
    [self postGroup:tweet group:group attach:nil];
}


- (void) postGroup:(NSString*)tweet group:(FriendGroup*)group attach:(NSDictionary*)attach
{
    needAuth = true;
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodPostTweet format:@"json"];
    NSString* postString = [NSString stringWithFormat:@"content=%@&ossource=MB&ossourceName=iphone&groupIds=%lld",
                            [tweet encodeAsURIComponent], group.groupId];

    
    if ( attach && [attach count] > 0 ) {
        NSString* attachPath = [attach objectForKey:@"attachPath"];
        NSString* attachType = [attach objectForKey:@"attachType"];
        NSString* attachFilename = [attach objectForKey:@"attachFilename"];
        postString = [postString stringByAppendingFormat:@"?attachPath=%@&attachType=%@&attachFilename=%@", [attachPath encodeAsURIComponent], attachType, [attachFilename encodeAsURIComponent] ];
    }

    [self post:url body:postString];
}


- (void) repost
{
    
}


- (void)send:(NSString*)text to:(NSString*)user
{
    needAuth = true;
    //NSString* url = @"http://api.t.sina.com.cn/direct_messages/new.json";
    NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodMessageSend format:@"json"];
    NSString *postString = [NSString stringWithFormat:@"text=%@&recipient_screen_name=%@", [text encodeAsURIComponent], [user encodeAsURIComponent]];
    [self post:url body:postString];
}


- (void)sendGroup:(NSString*)text group:(FriendGroup*)group
{
    needAuth = true;
    NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodMessageSendToGroup format:@"json"];
    NSString *postString = [NSString stringWithFormat:@"text=%@&recipient_group_id=%lld", [text encodeAsURIComponent], group.groupId];
    [self post:url body:postString];
}


- (void)getFriends:(NSString*)screen_name page:(int)page isFollowers:(BOOL)isFollowers
{
    needAuth = true;
	//changed by zhaoqi
    //NSString* url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/statuses/%@/%@.json?page=%d",
    //                (isFollowers) ? @"followers" : @"friends", [screen_name encodeAsURIComponent], page];
	NSString* url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/statuses/%@.json?screen_name=%@&cursor=%d",
					 (isFollowers) ? @"followers" : @"friends", 
					 [screen_name encodeAsURIComponent], page];
	
    [self get:url];
}



+ (NSArray*) getFriendsSync:(sqlite_int64)userId page:(int)page rowsPerPage:(int)rowsPerPage
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipFollowing format:@"json"];
	NSString* url = [NSString stringWithFormat:@"%@?userId=%lld&pageNo=%d&rowsPerPage=%d&needURL=N&needFace=N", s, userId, page, rowsPerPage];
	NSHTTPURLResponse* response;
	NSError* error;
	
	NSMutableArray* users = [NSMutableArray array];
	
	id result = [TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 && result != nil && [result isKindOfClass:[NSArray class]] ) {
		NSArray* arr = (NSArray*) result;
		if ( arr != nil && ![[NSNull null] isEqual:arr] && [arr count] > 0 ) {
			for ( int i=0; i<[arr count]; i++ ) {
				NSDictionary* userDic = [arr objectAtIndex:i];
				if ( userDic == nil || ![userDic isKindOfClass:[NSDictionary class]] ) continue;
				User* user = [[User alloc] initWithJsonDictionary:userDic];
				[users addObject:user];
				[user release];
			}
		}
	}
	
	return users;
}


- (void)getFriendsByUserId:(sqlite_int64)userId page:(int)page isFollowers:(BOOL)isFollowers
{
    [self getFriendsByUserId:userId page:page rows:20 orderby:1 isFollowers:isFollowers];
}


- (void)getFriendsByUserId:(sqlite_int64)userId page:(int)page rows:(int)rows orderby:(int)orderby isFollowers:(BOOL)isFollowers
{
    needAuth = true;
	
	NSString* s = nil;
	if ( isFollowers ) {
		s = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipFollowers format:@"json"];
	}
	else {
		s = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipFollowing format:@"json"];
	}
	
	NSString* url = [NSString stringWithFormat:@"%@?userId=%lld&pageNo=%d&rowsPerPage=%d&orderBy=%d&needURL=N&needFace=N", s, userId, page, rows, orderby];
    
    [self get:url];
	
}



- (void)friendship:(sqlite_int64)userId create:(BOOL)create
{
    needAuth = true;
    request = (create) ? TWITTER_REQUEST_CREATE_FRIENDSHIP : TWITTER_REQUEST_DESTROY_FRIENDSHIP;
    //changed by zhaoqi
	//NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/friendships/%@/%@.json",
    //                 create ? @"create" : @"destroy",
    //                 screen_name];
	//NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/friendships/%@.json?screen_name=%@",
    //                 create ? @"create" : @"destroy",
    //                 [screen_name encodeAsURIComponent]];
	
	NSString* url = nil;
	NSString* data = [NSString stringWithFormat:@"userId=%lld", userId];;
	if ( create ) {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipCreate format:@"json"];
	}
	else {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipDestroy format:@"json"];
	}
	
    [self post:url body:data];
}


+ (BOOL) createFriendshipSync:(sqlite3_int64)userId
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipCreate format:@"json"];
	NSString* url = nil;
	NSHTTPURLResponse* response;
	NSError* error;
    
	url = [NSString stringWithFormat:@"%@?userId=%lld", s, userId];
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
		return YES;
	}
	else {
		return false;
	}
    return false;
}


+ (BOOL) destroyFriendshipSync:(sqlite3_int64)userId
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipDestroy format:@"json"];
	NSString* url = nil;
	NSHTTPURLResponse* response;
	NSError* error;
    
	url = [NSString stringWithFormat:@"%@?userId=%lld", s, userId];
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
		return YES;
	}
	else {
		return false;
	}
    return false;
}


- (void)existFriendship:(NSString*)screen_name
{
    needAuth = true;
    request = TWITTER_REQUEST_FRIENDSHIP_EXISTS;
    NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:@"username"];
    
    NSString *url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/friendships/exists.json?user_a=%@&user_b=%@",
                     [username encodeAsURIComponent],
                     [screen_name encodeAsURIComponent]];
    
    [self post:url body:@""];
}

- (void)destroy:(Tweet*)tweet
{
    needAuth = true;

    NSString *url;
    if ([tweet isKindOfClass:[Status class]]) {
        Status *status = (Status*)tweet;
        //url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/statuses/destroy/:%lld.json", status.statusId];
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodDestroyTweet format:@"json"];
		[self post:url body:[NSString stringWithFormat:@"weiboId=%lld",status.tweetId]];
    }
    else {
        DirectMessage *message = (DirectMessage*)tweet;
        url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/direct_messages/destroy/:%lld.json", message.messageId];
		[self post:url body:@""];
    }
    
}

- (void)favorites:(NSString*)screenName page:(int)page
{
    needAuth = true;
	
    NSString *s = [[URLStore sharedInstance] urlForKey:kAPIMethodFavoriteList format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?pageNo=%d&rowsPerPage=20",s,page];
	
    //if (screenName) {
	//TODO: commented by zhaoqi. no this api?
	//     url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/favorites/%@.json?page=%d", screenName, page];
    //}
    //else {
    //    url = @"http://api.t.sina.com.cn/favorites.json";
    //}
    
    [self get:url];
}


- (void)toggleFavorite:(Status*)status
{
    needAuth = true;
    request = (status.favorited) ? TWITTER_REQUEST_DESTROY_FAVORITE : TWITTER_REQUEST_FAVORITE;
    
//    NSString* url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/favorites/%@/%lld.json",
//                     (status.favorited) ? @"destroy" : @"create",
//                     status.statusId];
//	changed by zhaoqi
//	NSString* url = [NSString stringWithFormat:@"http://api.t.sina.com.cn/favorites/%@.json?id=%lld", 
//					 (status.favorited) ? @"destroy" : @"create", 
//					 status.statusId ];
	
	NSString* url = nil;
	NSString* data = nil;
	if ( status.favorited ) {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodFavoriteDestroy format:@"json"];
		data = [NSString stringWithFormat:@"favoritesIds=%lld", status.statusId];
	}
	else {
		url = [[URLStore sharedInstance] urlForKey:kAPIMethodFavoriteCreate format:@"json"];
		data = [NSString stringWithFormat:@"type=WEIBO&refId=%lld", status.statusId];
	}
	
    
    [self post:url body:data];    
}



- (void)updateLocation:(float)latitude longitude:(float)longitude
{
    //TODO: no this api? zhaoqi
    needAuth = true;
	NSString* url = @"http://api.t.sina.com.cn/account/update_location.json";
    
    NSString *postString = [NSString stringWithFormat:@"location=iPhone: %f,%f", latitude, longitude];
    
    [self post:url body:postString];
}


- (void)updateLocation:(NSString*)tweet latitude:(float)latitude longitude:(float)longitude
{
    needAuth = true;
    
    NSString* url = @"http://api.t.sina.com.cn/statuses/update.json";
    NSString *postString = [NSString stringWithFormat:@"status=%@&lat=%f&long=%f",
                            [tweet encodeAsURIComponent],
                            latitude, longitude];
	
    [self post:url body:postString];
    
}


- (void)search:(NSString*)query
{
    NSMutableString *url = [NSMutableString stringWithString:@"http://api.t.sina.com.cn/search.json"];
    [url appendString:query];
    [self get:url];
}

- (void)trends
{
	//commented by zhaoqi: error, because absent parameter 'user_id' according to sina's api
    [super get:@"http://api.t.sina.com.cn/trends.json"];
}

- (void)verify
{
    needAuth = true;
	//NSString* url = @"http://api.t.sina.com.cn/account/verify_credentials.json";
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodVerify format:kAPIFormatJSON];
    
    [super get:url];
}


+ (User*) verifyAccount
{
    NSString* username = [GuaziAppDelegate getAppDelegate].user.name;
    NSString* password = [GuaziAppDelegate getAppDelegate].user.password;
    return [self verifyAccount:username password:password];
}


+ (User*) verifyAccount:(NSString*)username password:(NSString*)password
{
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodVerify format:@"json"];
	NSHTTPURLResponse* response;
	NSError* error;
	id result = [TFConnection sendSynchronousRequest:url username:username password:password response:&response error:&error];
	if ( response.statusCode == 200 && [result isKindOfClass:[NSDictionary class]] ) {
		NSDictionary* dic = (NSDictionary*) result;
		User* account = [[[User alloc] initWithJsonDictionary:dic] autorelease];
		return account;
	}
	else {
		return nil;
	}
}


+ (NSArray*) getGroups
{
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodGroupGetGroups format:@"json"];
	NSHTTPURLResponse* response;
	NSError* error;
	
	FriendGroup* group = nil;
    NSMutableDictionary* groups = [NSMutableDictionary dictionary];
    NSMutableArray* groupList = [NSMutableArray array];
	
	id result = [TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 && [result isKindOfClass:[NSArray class]] ) {
		NSArray* arr = (NSArray*) result;
		for ( int i=0; i<[arr count]; i++ ) {
			NSDictionary* dic = [arr objectAtIndex:i];
			group = [FriendGroup groupWithDictionary:dic];
            
            NSString* key = [NSString stringWithFormat:@"%lld", group.groupId];
            if ( [groups objectForKey:key] == nil ) {
                [groups setObject:@"" forKey:key];
                [groupList addObject:group];
            }
		}
	}
	
	return groupList;
}


- (void) getUsersInGroup:(sqlite_int64)groupId
{
    needAuth = true;
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodGroupUsers format:@"json"];
	NSString* url = [NSString stringWithFormat:@"%@?groupId=%lld&pageNo=0&rowsPerPage=2000&needURL=N&needFace=N", s, groupId];
	[self get:url];
}


+ (NSMutableArray*) getUserInGroupSync:(sqlite_int64)groupId
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodGroupUsers format:@"json"];
	NSString* url = [NSString stringWithFormat:@"%@?groupId=%lld&pageNo=0&rowsPerPage=2000&needURL=N&needFace=N", s, groupId];
	NSHTTPURLResponse* response;
	NSError* error;
	
	NSMutableArray* users = [NSMutableArray array];
	
	id result = [TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 && result != nil && [result isKindOfClass:[NSDictionary class]] ) {
		NSDictionary* dic = (NSDictionary*) result;
		NSArray* arr = [dic objectForKey:@"friends"];
		if ( arr != nil && ![[NSNull null] isEqual:arr] && [arr count] > 0 ) {
			for ( int i=0; i<[arr count]; i++ ) {
				NSDictionary* userDic = [arr objectAtIndex:i];
				if ( userDic == nil || ![userDic isKindOfClass:[NSDictionary class]] ) continue;
				User* user = [[User alloc] initWithJsonDictionary:userDic];
				[users addObject:user];
				[user updateDB:YES withName:NO withAccount:NO];
				[user release];
			}
		}
	}
	
	return users;
}


+ (BOOL) setUserGroupsSync:(NSArray*)groupIds userId:(sqlite_int64)userId operation:(NSString*)op
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodFriendShipSetUserGroup format:@"json"];
	NSString* url = nil;
	NSString* groups = @"";
	
	if ( groupIds != nil && [groupIds count] > 0 ) {
		groups = [groupIds componentsJoinedByString:@","];
	}
	
	NSHTTPURLResponse* response;
	NSError* error;
	url = [NSString stringWithFormat:@"%@?friendId=%lld&groupIds=%@&op=%@", s, userId, groups, op];
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
		return YES;
	}
	else {
		return false;
	}
}


+ (BOOL) createUserGroupSync:(FriendGroup*)group
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodGroupCreate format:@"json"];

	NSHTTPURLResponse* response;
	NSError* error;
	NSString* url = [NSString stringWithFormat:@"%@?name=%@&acce=%d", s, [group.name encodeAsURIComponent], group.isPublic?kGroupAccePublic:kGroupAccePrivate];
	
	id result = [TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        if ( result && [result isKindOfClass:[NSDictionary class]]) {
            NSDictionary* dic = (NSDictionary*) result;
            id groupId = [dic objectForKey:@"groupId"];
            group.groupId = ((groupId==[NSNull null]) ? 0 : [groupId longLongValue]);
        }
	}
    
    if ( group.groupId > 0 ) return YES;
    else return false;
}


+ (BOOL) destroyUserGroupSync:(sqlite_int64)groupId
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodGroupDestroy format:@"json"];
	
	NSHTTPURLResponse* response;
	NSError* error;
	NSString* url = [NSString stringWithFormat:@"%@?groupId=%lld", s, groupId];
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
		return YES;
	}
	else {
		return false;
	}
}


+ (BOOL) updateUserGroupSync:(FriendGroup*)group
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodGroupUpdate format:@"json"];
	
	NSHTTPURLResponse* response;
	NSError* error;
	NSString* url = [NSString stringWithFormat:@"%@?groupId=%lld&name=%@&acce=%d", s, group.groupId, [group.name encodeAsURIComponent], group.isPublic?kGroupAccePublic:kGroupAccePrivate];
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
		return YES;
	}
	else {
		return false;
	}
}


- (void) searchUser:(NSString*)screenName
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodSearchUser format:@"json"];
	NSString* url = [NSString stringWithFormat:@"%@?nickname=%@&pageNo=0&rowsPerPage=200", s, [screenName encodeAsURIComponent]];
	NSLog(@"searchUser url=%@", url);
	
	needAuth = YES;
	[self get:url];
}


#pragma mark - 微博

- (void) loadStatus:(long long)statusId
{
    needAuth = YES;
    NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodTweetShow format:@"json"];
    url = [NSString stringWithFormat:@"%@?weiboId=%lld", url, statusId ];
    [self get:url];
}


- (void) retweet:(Status*)status
{
    needAuth = YES;
    Status* originStatus = status.originStatus;
    if ( !originStatus ) originStatus = status;
    
    NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodTweetRepost format:@"json"];
    NSString* data = [NSString stringWithFormat:@"content=%@&ossource=MB&ossourceName=iphone&lastForwardId=%lld&originId=%lld&originType=WEIBO&remarkToOrigin=NO&remarkToLastForwarder=NO", [originStatus.text encodeAsURIComponent], status.statusId, originStatus.statusId ];
    [self post:url body:data];
}


+ (BOOL) retweetSync:(Status*)status
{
    Status* originStatus = status.originStatus;
    if ( !originStatus ) originStatus = status;

    NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodTweetRepost format:@"json"];
    NSString* data = [NSString stringWithFormat:@"content=%@&ossource=MB&ossourceName=iphone&lastForwardId=%lld&originId=%lld&originType=WEIBO&remarkToOrigin=NO&remarkToLastForwarder=NO", [originStatus.text encodeAsURIComponent], status.statusId, originStatus.statusId ];
    
    int contentLength = [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSData* body = [NSData dataWithBytes:[data UTF8String] length:contentLength];
	NSHTTPURLResponse* response;
	NSError* error;
	
    [TFConnection sendSynchronousRequest:url method:@"POST" body:body response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        return NO;
    }
}


- (void) retweetUsers:(long long)statusId pageNo:(NSInteger)pageNo rowsPerPage:(NSInteger)rows
{
    needAuth = YES;
    
    NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMehtodTweetRetweetUsers format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?weiboId=%lld&pageNo=%d&rowsPerPage=%d", s, statusId, pageNo, rows];
    [self get:url];
}



#pragma mark - 评论

- (void) remarkList:(long long)statusId sinceTime:(time_t)sinceTime
{
    needAuth = YES;
    NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodRemarkList format:@"json"];
    if ( sinceTime > 0 ) {
        url = [NSString stringWithFormat:@"%@?refId=%lld&pageNo=0&rowsPerPage=200&sinceTime=%ld", url, statusId, sinceTime ];
    }
    else {
        url = [NSString stringWithFormat:@"%@?refId=%lld&pageNo=0&rowsPerPage=200", url, statusId ];
    }
    
    [self get:url];
}


+ (Remark*) publishRemarkSync:(Remark*)remark status:(Status*)originStatus
{
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodRemarkCreate format:@"json"];
    NSString* data = [NSString stringWithFormat:@"text=%@&refId=%lld&originBelonged=%lld&originId=%lld&needToForward=NO&remarkToOrigin=NO&ossource=MB&ossourceName=iphone", [remark.text encodeAsURIComponent], originStatus.statusId, originStatus.user.userId, originStatus.statusId];
    
	NSHTTPURLResponse* response;
	NSError* error;
	
    id result = [TFConnection sendSynchronousRequest:url body:data response:&response error:&error];
	if ( response.statusCode == 200 ) {
        if ( result && [result isKindOfClass:[NSDictionary class]]) {
            NSDictionary* dic = (NSDictionary*) result;
            Remark* resultRemark = [[[Remark alloc] initWithJsonDictionary:dic statusId:originStatus.statusId] autorelease];
            return resultRemark;
        }
	}
    
    return nil;
}


#pragma mark - 默默关注
- (void) getSilenceFollowings
{
    needAuth = YES;
    NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodSilenceFollowing format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?needURL=N&needFace=N&pageNo=0&rowsPerPage=1000",s];
    [self get:url];
}


+ (BOOL) createSilenceFollowingSync:(sqlite3_int64)userId 
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodCreateSilenceFollowing format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?refId=%lld", s, userId];
	NSHTTPURLResponse* response;
	NSError* error;
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        return NO;
    }
}


+ (BOOL) destroySilenceFollowingSync:(sqlite3_int64)userId
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodDestroySilenceFollowing format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?refId=%lld", s, userId];
	NSHTTPURLResponse* response;
	NSError* error;
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        return NO;
    }
}


#pragma mark - 名片

- (void) getMyCards
{
    needAuth = YES;
    NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodCardMyCards format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?needURL=N&needFace=N&pageNo=0&rowsPerPage=1000",s];
    [self get:url];
}


- (void) askCard:(long long)userId
{
    needAuth = YES;
    NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodCardAskCard format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?targetUserId=%lld",s, userId];
    [self get:url];
}


+ (BOOL) acceptAskCardSync:(NSString*)askId dmId:(long long)dmId cardId:(long long)cardId
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodCardAskCardAccept format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?askId=%@&myCardId=%lld&letterId=%lld", s, askId, dmId, cardId];
	NSLog(@"%@",url);
    NSHTTPURLResponse* response;
	NSError* error;
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        return NO;
    }
}


+ (BOOL) rejectAskCardSync:(NSString*)askId dmId:(long long)dmId message:(NSString*)message
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodCardAskCardReject format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?askId=%@&letterId=%lld&rejectReason=%@", s, askId, dmId, [message encodeAsURIComponent]];
	NSHTTPURLResponse* response;
	NSError* error;
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        return NO;
    }
}



#pragma mark - 注册

+ (BOOL) registerSync:(long long)userId name:(NSString*)name password:(NSString*)password
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodRegisterRegister format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?userId=%lld&username=%@&password=%@", s, userId, [name encodeAsURIComponent], [password encodeAsURIComponent] ];
	NSHTTPURLResponse* response;
	NSError* error;
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        return NO;
    }
}


+ (BOOL) activateSync:(long long)userId activateCode:(NSString*)code  screenName:(NSString*)name password:(NSString*)password
{
	NSString* s = [[URLStore sharedInstance] urlForKey:kAPIMethodRegisterActivate format:@"json"];
    NSString* url = [NSString stringWithFormat:@"%@?activeCode=%@&userId=%lld&nickname=%@&password=%@", s, code, userId, [name encodeAsURIComponent], [password encodeAsURIComponent] ];
	NSHTTPURLResponse* response;
	NSError* error;
	
	[TFConnection sendSynchronousRequest:url response:&response error:&error];
	if ( response.statusCode == 200 ) {
        return YES;
	}
    else {
        NSLog(@"code=%d", response.statusCode);
        return NO;
    }
}



#pragma mark - 数据上传
- (void) dataup:(NSArray*)records
{
	if ( records == nil || [records count]==0 ) return;
    
    NSMutableString* s = [NSMutableString stringWithString:@""];
    for ( OperationLog* log in records ) {
        [s appendFormat:@",%@", [log toString]];
    }
    
    NSRange range;
    range.location = 0;
    range.length = 1;
    [s deleteCharactersInRange:range];
    [s insertString:@"[" atIndex:0];
    [s appendString:@"]"];
    NSLog(@"%@",s);
    
    NSString* data = [NSString stringWithFormat:@"data=%@", [s encodeAsURIComponent]];
    NSLog(@"%@",data);
    
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodDataup format:@"json"];
    NSLog(@"%@",url);
    
	needAuth = YES;
    
	[self post:url body:data];
}


+ (id) dataupSync:(NSArray *)records response:(NSHTTPURLResponse**)response error:(NSError**)error
{
	if ( records == nil || [records count]==0 ) return nil;
    
    NSMutableString* s = [NSMutableString stringWithString:@""];
    for ( OperationLog* log in records ) {
        [s appendFormat:@",%@", [log toString]];
    }
    
    NSRange range;
    range.location = 0;
    range.length = 1;
    [s deleteCharactersInRange:range];
    [s insertString:@"[" atIndex:0];
    [s appendString:@"]"];
    NSLog(@"%@",s);
    
    NSString* data = [NSString stringWithFormat:@"data=%@", [s encodeAsURIComponent]];
    NSLog(@"%@",data);
    
	NSString* url = [[URLStore sharedInstance] urlForKey:kAPIMethodDataup format:@"json"];
    
    int contentLength = [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"length=%d", contentLength);
    
    NSData* body = [NSData dataWithBytes:[data UTF8String] length:contentLength];
	id object = [TFConnection sendSynchronousRequest:url method:@"POST" body:body response:response error:error];
    return object;
}



- (void)authError
{
    self.errorMessage = @"帐户验证失败";
    self.errorDetail  = @"错误的用户名或者密码";    
    [delegate performSelector:action withObject:self withObject:nil];    
}

- (void)TFConnectionDidFailWithError:(NSError*)error
{
    hasError = true;
    if (error.code ==  NSURLErrorUserCancelledAuthentication) {
        statusCode = 401;
        [self authError];
    }
    else {
        self.errorMessage = @"Connection Failed";
        self.errorDetail  = [error localizedDescription];
        [delegate performSelector:action withObject:self withObject:nil];
    }
    [self autorelease];
}

-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge previousFailureCount] == 0) {
        NSLog(@"Authentication Challenge");
        NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:@"username"];
        NSString *password = [[NSUserDefaults standardUserDefaults] stringForKey:@"password"];
        NSURLCredential* cred = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
        [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
    } else {
        NSLog(@"Failed auth (%d times)", [challenge previousFailureCount]);
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    hasError = true;
    [self authError];
    [self autorelease];
}

- (void)TFConnectionDidFinishLoading:(NSString*)content
{
    switch (statusCode) {
        case 401: // Not Authorized: either you need to provide authentication credentials, or the credentials provided aren't valid.
            hasError = true;
            [self authError];
            goto out;
            
        case 304: // Not Modified: there was no new data to return.
            [delegate performSelector:action withObject:self withObject:nil];
            goto out;
            
        case 400: // Bad Request: your request is invalid, and we'll return an error message that tells you why. This is the status code returned if you've exceeded the rate limit
        case 200: // OK: everything went awesome.
        case 403: // Forbidden: we understand your request, but are refusing to fulfill it.  An accompanying error message should explain why.
            break;
                
        case 404: // Not Found: either you're requesting an invalid URI or the resource in question doesn't exist (ex: no such user). 
        case 500: // Internal Server Error: we did something wrong.  Please post to the group about it and the Twitter team will investigate.
        case 502: // Bad Gateway: returned if Twitter is down or being upgraded.
        case 503: // Service Unavailable: the Twitter servers are up, but are overloaded with requests.  Try again later.
        default:
        {
            hasError = true;
            self.errorMessage = @"抱歉，服务器发生内部错误";
            self.errorDetail  = [NSHTTPURLResponse localizedStringForStatusCode:statusCode];
            [delegate performSelector:action withObject:self withObject:nil];
            goto out;
        }
    }
#if 0
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *pathStr;
    if (request == 0) {
        pathStr = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"friends_timeline.json"];
    }
    else if (request == 1) {
        pathStr = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"replies.json"];
    }
    else if (request == 2) {
        pathStr = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"direct_messages.json"];
    }
    if (request <= 2) {
        NSData *data = [fileManager contentsAtPath:pathStr];
        content = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
    }
#endif

    NSObject *obj = [content JSONValue];
    if (request == TWITTER_REQUEST_FRIENDSHIP_EXISTS) {
        NSRange r = [content rangeOfString:@"true" options:NSCaseInsensitiveSearch];
  	  	obj = [NSNumber numberWithBool:r.location != NSNotFound];
    }
    
    if ([obj isKindOfClass:[NSDictionary class]]) {
        NSDictionary* dic = (NSDictionary*)obj;
        NSString *msg = [dic objectForKey:@"error"];
        if (msg) {
            NSLog(@"系统发生错误: %@", msg);
            hasError = true;
            self.errorMessage = @"服务器错误	";
            self.errorDetail  = msg;
        }
    }
    
    [delegate performSelector:action withObject:self withObject:obj];
    
  out:
    [self autorelease];
}

- (void)alert
{
	[GuaziAppDelegate showAlert:errorMessage message:errorDetail];
}

@end
